/****************************************************************************
 *  QLyrics - A simple lyrics viewer.                                       *
 *  Copyright (C) 2008  hsys <hanshuiys@gmail.com>                          *
 *                                                                          *
 *  This program is free software; you can redistribute it and/or modify    *
 *  it under the terms of the GNU General Public License as published by    *
 *  the Free Software Foundation; either version 3 of the License, or       *
 *  (at your option) any later version.                                     *
 *                                                                          *
 *  This program is distributed in the hope that it will be useful,         *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 *  GNU General Public License for more details.                            *
 *                                                                          *
 *  You should have received a copy of the GNU General Public License       *
 *  along with this program; if not, write to the Free Software Foundation, *
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA       *
 ****************************************************************************/

#ifndef _FACTORY_H_
#define _FACTORY_H_

#include <vector>
#include <QString>

template <typename T>
class Factory {
public:
    class BaseRegister {
        const QString m_name;
    public:
        BaseRegister(const char* name = NULL) : m_name(name) {
            Factory<T>* inst = Factory<T>::getInstance();
            inst->add(this);
        };
        const QString& getName() const { return m_name; };
        virtual T* create() const = 0;
    };
    template <typename C>
        class Register : public BaseRegister {
        public:
            Register(const char* name = NULL) : BaseRegister(name) {};
            virtual T* create() const { return new C(); };
        };
    int size() const { return m_type.size(); };
    void add(BaseRegister* type) { m_type.push_back(type); };
    const BaseRegister* get(int id) const { return m_type.at(id); };
    const BaseRegister* find(const QString& name) const {
        for (int i = 0; i < m_type.size(); i++) {
            if (m_type[i]->getName() == name)
                return m_type[i];
        };
        return m_type[0];
    };
    static Factory<T>* getInstance() {
        static Factory<T> inst;
        return &inst;
    };

protected:
    std::vector<BaseRegister*> m_type;

};

#endif /* _FACTORY_H_ */

